package biz.datalk.industrialland.common.util;

import biz.datalk.commons.utils.json.JsonUtil;
import com.aliyuncs.DefaultAcsClient;
import com.aliyuncs.IAcsClient;
import com.aliyuncs.auth.sts.AssumeRoleRequest;
import com.aliyuncs.auth.sts.AssumeRoleResponse;
import com.aliyuncs.dysmsapi.model.v20170525.QuerySendDetailsRequest;
import com.aliyuncs.dysmsapi.model.v20170525.QuerySendDetailsResponse;
import com.aliyuncs.dysmsapi.model.v20170525.SendSmsRequest;
import com.aliyuncs.dysmsapi.model.v20170525.SendSmsResponse;
import com.aliyuncs.exceptions.ClientException;
import com.aliyuncs.http.MethodType;
import com.aliyuncs.http.ProtocolType;
import com.aliyuncs.profile.DefaultProfile;
import com.aliyuncs.profile.IClientProfile;
import org.apache.commons.lang3.StringUtils;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.TimeZone;

/**
 * Created by alex on 2017/11/6.
 */

public class AliyunUtil {

    // 阿里云主账号的AccessKeys不能用于发起AssumeRole请求
    // 请首先在RAM控制台创建一个RAM用户，并为这个用户创建AccessKeys
    private final static String accessKeyId = "******";
    private final static String accessKeySecret = "******";

    // 目前只有"cn-hangzhou"这个region可用, 不要使用填写其他region的值
    private static final String REGION_CN_HANGZHOU = "cn-hangzhou";
    // 当前 STS API 版本
    private static final String STS_API_VERSION = "2015-04-01";
    // 只有 RAM用户（子账号）才能调用 AssumeRole 接口
    //RoleArn 需要在 RAM 控制台上获取
    private final static String roleArn = "acs:ram::1847469002609586:role/ydskossfulluser";
    // RoleSessionName 是临时Token的会话名称，自己指定用于标识你的用户，主要用于审计，或者用于区分Token颁发给谁
    private final static String roleSessionName = "cdydsk-app";

    //Endpoint
    private final static String endpoint = "https://oss-cn-hangzhou.aliyuncs.com";

    // 定制policy?
    private final static String policy = "{\n" +
            "  \"Statement\": [\n" +
            "    {\n" +
            "      \"Action\": \"oss:*\",\n" +
            "      \"Effect\": \"Allow\",\n" +
            "      \"Resource\": \"*\"\n" +
            "    }\n" +
            "  ],\n" +
            "  \"Version\": \"1\"\n" +
            "}";

    private static AssumeRoleResponse theResponse = null;
    private static long expiration = 0l;

    //Aliyun STS
    private static AssumeRoleResponse assumeRole() throws ClientException {
        try {
            // 创建一个 Aliyun Acs Client, 用于发起 OpenAPI 请求
            IClientProfile profile = DefaultProfile.getProfile(REGION_CN_HANGZHOU, accessKeyId, accessKeySecret);
            DefaultAcsClient client = new DefaultAcsClient(profile);
            // 创建一个 AssumeRoleRequest 并设置请求参数
            AssumeRoleRequest request = new AssumeRoleRequest();
            request.setVersion(STS_API_VERSION);
            request.setMethod(MethodType.POST);
            request.setProtocol(ProtocolType.HTTPS);
            request.setRoleArn(roleArn);
            request.setRoleSessionName(roleSessionName);
            request.setPolicy(policy);
            // 发起请求，并得到response
            AssumeRoleResponse response = client.getAcsResponse(request);
            return response;
        } catch (ClientException e) {
            throw e;
        }
    }

    public static AssumeRoleResponse getAssumeRole() throws ClientException {
        long nowTime = new Date().getTime();
        if (theResponse == null || expiration < nowTime) {
            theResponse = assumeRole();
            SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'");
            df.setTimeZone(TimeZone.getTimeZone("UTC"));
            try {
                Date eDate = df.parse(theResponse.getCredentials().getExpiration());
                expiration = eDate.getTime();
            } catch (ParseException e) {
                e.printStackTrace();
            }
        }
        return theResponse;
    }


    //产品名称:云通信短信API产品,开发者无需替换
    static final String dysmsProduct = "Dysmsapi";
    //产品域名,开发者无需替换
    static final String dysmsDomain = "dysmsapi.aliyuncs.com";

    public static SendSmsResponse sendSms(String mobNum, String templateCode, String templateParam, String outId) throws ClientException {
        return sendSms(accessKeyId, accessKeySecret, null, mobNum, templateCode, templateParam, outId);
    }

    public static SendSmsResponse sendSms(String ak, String sk, String signName, String mobNum, String templateCode, String templateParam, String outId) throws ClientException {
        String tmpSignName = StringUtils.isNoneBlank(signName) ? signName : "达拓智通";

        //可自助调整超时时间
        System.setProperty("sun.net.client.defaultConnectTimeout", "10000");
        System.setProperty("sun.net.client.defaultReadTimeout", "10000");

        //初始化acsClient,暂不支持region化
        IClientProfile profile = DefaultProfile.getProfile(REGION_CN_HANGZHOU, ak, sk);
        DefaultProfile.addEndpoint(REGION_CN_HANGZHOU, REGION_CN_HANGZHOU, dysmsProduct, dysmsDomain);
        IAcsClient acsClient = new DefaultAcsClient(profile);

        //组装请求对象-具体描述见控制台-文档部分内容
        SendSmsRequest request = new SendSmsRequest();
        //必填:待发送手机号
        request.setPhoneNumbers(mobNum);
        //必填:短信签名-可在短信控制台中找到
        request.setSignName(tmpSignName);
        //必填:短信模板-可在短信控制台中找到
        request.setTemplateCode(templateCode);
        //可选:模板中的变量替换JSON串,如模板内容为"亲爱的${name},您的验证码为${code}"时,此处的值为
        //"{\"name\":\"Tom\", \"code\":\"123\"}"
        request.setTemplateParam(templateParam);

        //选填-上行短信扩展码(无特殊需求用户请忽略此字段)
        //request.setSmsUpExtendCode("90997");

        //可选:outId为提供给业务方扩展字段,最终在短信回执消息中将此值带回给调用者
        request.setOutId(outId);

        //hint 此处可能会抛出异常，注意catch
        SendSmsResponse sendSmsResponse = acsClient.getAcsResponse(request);

        return sendSmsResponse;
    }


    public static QuerySendDetailsResponse querySendDetails(String mobNum, Date queryDate, String bizId) throws ClientException {
        return querySendDetails(accessKeyId, accessKeySecret, mobNum, queryDate, bizId);
    }
    public static QuerySendDetailsResponse querySendDetails(String ak, String sk, String mobNum, Date queryDate, String bizId) throws ClientException {

        //可自助调整超时时间
        System.setProperty("sun.net.client.defaultConnectTimeout", "10000");
        System.setProperty("sun.net.client.defaultReadTimeout", "10000");

        //初始化acsClient,暂不支持region化
        IClientProfile profile = DefaultProfile.getProfile(REGION_CN_HANGZHOU, ak, sk);
        DefaultProfile.addEndpoint(REGION_CN_HANGZHOU, REGION_CN_HANGZHOU, dysmsProduct, dysmsDomain);
        IAcsClient acsClient = new DefaultAcsClient(profile);

        //组装请求对象
        QuerySendDetailsRequest request = new QuerySendDetailsRequest();
        //必填-号码
        request.setPhoneNumber(mobNum);
        //可选-流水号
        request.setBizId(bizId);
        //必填-发送日期 支持30天内记录查询，格式yyyyMMdd
        SimpleDateFormat ft = new SimpleDateFormat("yyyyMMdd");
        request.setSendDate(ft.format(queryDate));
        //必填-页大小
        request.setPageSize(10L);
        //必填-当前页码从1开始计数
        request.setCurrentPage(1L);

        //hint 此处可能会抛出异常，注意catch
        QuerySendDetailsResponse querySendDetailsResponse = acsClient.getAcsResponse(request);

        return querySendDetailsResponse;
    }

    public static void main(String[] args) throws ClientException {
        Map<String, String> params = new HashMap<>();
        params.put("name", "杨磊");
        params.put("phone", "14780001553");
        params.put("time", "2022-12-14 15:00-16:00");
        params.put("carNumber", "川A 58369");
        params.put("time2", "2022-12-14 14:30 ~ 2022-12-14 16:30");
        SendSmsResponse resp = AliyunUtil.sendSms("14780001553", "SMS_264101210", JsonUtil.getJsonFromObject(params), null);
        if ("OK".equals(resp.getCode())) {
            System.out.println("政务预约提醒短信发送成功 ： 14780001553 SMS_264101210");
        } else {
            System.out.println("政务预约提醒短信发送失败 ： 14780001553 SMS_264101210 " + resp.getMessage());
        }
    }
}
